home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-11 | 63.7 KB | 2,012 lines |
- //=============================================================================
- //
- // Copyright (C) 1995, 1996 by Paul S. McCarthy and Eric Sunshine.
- // Written by Paul S. McCarthy and Eric Sunshine.
- // All Rights Reserved.
- //
- // This notice may not be removed from this source code.
- //
- // This object is included in the MiscKit by permission from the authors
- // and its use is governed by the MiscKit license, found in the file
- // "License.rtf" in the MiscKit distribution. Please refer to that file
- // for a list of all applicable permissions and restrictions.
- //
- //=============================================================================
- //-----------------------------------------------------------------------------
- // MiscTableScroll.M
- //
- // ScrollView class that displays a 2-D table of cells.
- //
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // $Id: MiscTableScroll.M,v 1.18 96/01/16 19:55:04 zarnuk Exp $
- // $Log: MiscTableScroll.M,v $
- // Revision 1.18 96/01/16 19:55:04 zarnuk
- // Turns off display in -free.
- // Does not call -update after calling -setAutodisplay:
- // More careful about suppressing auto-sort after a drag.
- //
- // Revision 1.17 96/01/13 23:33:54 zarnuk
- // Pulled-out sorting stuff into (Sort) category.
- // New version (1), since range of sortType values increased.
- // Plugged some memory leaks.
- // No longer tries to resort when "skip" slots are dragged.
- //
- // Revision 1.16 95/12/19 23:16:38 sunshine
- // Fixed MiscTableBorder.cc:1107: failed assertion
- //
- // Revision 1.15 95/12/17 15:11:35 zarnuk
- // Added -border:sortSlot:, -sortCol:, -sortRow:.
- //
- // Revision 1.14 95/10/20 00:12:40 sunshine
- // Was including MiscTableScroll.h and MiscTableCell.h with "" instead of <>.
- //-----------------------------------------------------------------------------
- #import <misckit/MiscTableScroll.h>
- #import <misckit/MiscTableCell.h>
- #import "MiscTableBorder.h"
- #import "MiscTableView.h"
- #import "MiscColView.h"
- #import "MiscRowView.h"
- #import "MiscNullView.h"
-
- #import <new.h>
-
- extern "Objective-C" {
- #import <appkit/Application.h>
- #import <appkit/Cell.h>
- #import <appkit/ClipView.h>
- #import <appkit/Font.h>
- #import <appkit/FontManager.h>
- }
-
- extern "C" {
- #import <assert.h>
- #import <math.h>
- #import <strings.h>
- }
-
- // There are no structural differences between versions 0 and 1. However,
- // the range of the MiscSortType values increased from 0..8 to 0..12
- #define MISC_TS_VERSION_0 0
- #define MISC_TS_VERSION_1 1
- #define MISC_TS_VERSION MISC_TS_VERSION_1
-
- @implementation MiscTableScroll
-
- //-----------------------------------------------------------------------------
- // + initialize
- //-----------------------------------------------------------------------------
- + initialize
- {
- if (self == [MiscTableScroll class])
- {
- [self setVersion: MISC_TS_VERSION];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // Tag Stuff
- //-----------------------------------------------------------------------------
- - (int) tag { return tag; }
- - setTag:(int) x { tag = x; return self; }
-
-
- //-----------------------------------------------------------------------------
- // -nextText
- //-----------------------------------------------------------------------------
- - nextText { return nextText; }
- - previousText { return previousText; }
- - setNextText:obj
- {
- nextText = obj;
- if (obj && [obj respondsTo: @selector(setPreviousText:)])
- [obj setPreviousText: self];
- return self;
- }
- - setPreviousText:obj { previousText = obj; return self; }
- - (BOOL) isSelectable { return YES; }
- - (BOOL) isEnabled { return enabled; }
- - setEnabled:(BOOL)flag { enabled = flag; return self; }
-
- - selectText:sender
- {
- if ([window firstResponder] != (id)tableView)
- [window makeFirstResponder:tableView];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // Multicast Messages
- //-----------------------------------------------------------------------------
- - sendAction:(SEL)aSel to:obj forAllCells:(BOOL)flag
- {
- int const rlim = num_rows;
- int const clim = num_cols;
- for (int r = 0; r < rlim; r++)
- for (int c = 0; c < clim; c++)
- if (flag || [self cellIsSelected:r:c])
- if (![obj perform:aSel with:[self cellAt:r:c]])
- return self;
- return self;
- }
-
- - (int) makeCellsPerform:(SEL)aSel with:p1 with:p2 selectedOnly:(BOOL)flag
- {
- int count = 0;
- int const rlim = num_rows;
- int const clim = num_cols;
- for (int r = 0; r < rlim; r++)
- for (int c = 0; c < clim; c++)
- if (!flag || [self cellIsSelected:r:c])
- {
- id cell = [self cellAt:r:c];
- if ([cell respondsTo:aSel])
- if ([cell perform:aSel with:p1 with:p2])
- count++;
- else
- return count;
- }
- return count;
- }
-
- - (int) makeCellsPerform:(SEL)aSel with:p1 selectedOnly:(BOOL)flag
- { return [self makeCellsPerform:aSel with:p1 with:0 selectedOnly:flag]; }
- - (int) makeCellsPerform:(SEL)aSel selectedOnly:(BOOL)flag
- { return [self makeCellsPerform:aSel with:0 with:0 selectedOnly:flag]; }
-
- - (int) makeCellsPerform:(SEL)aSel
- { return [self makeCellsPerform:aSel selectedOnly:NO]; }
- - (int) makeCellsPerform:(SEL)aSel with:p1
- { return [self makeCellsPerform:aSel with:p1 selectedOnly:NO]; }
- - (int) makeCellsPerform:(SEL)aSel with:p1 with:p2
- { return [self makeCellsPerform:aSel with:p1 with:p2 selectedOnly:NO];}
-
-
- //-----------------------------------------------------------------------------
- // FINDING CELLS
- //-----------------------------------------------------------------------------
-
- - (int) border:(MiscBorderType)b findSlotWithTag:(int)x
- {
- int const lim = (int) [self numSlots:b];
- for (int i = 0; i < lim; i++)
- if ([self border:b slotTag:i] == x)
- return i;
- return -1;
- }
- - (int) findColWithTag:(int)x
- { return [self border:MISC_COL_BORDER findSlotWithTag:x]; }
- - (int) findRowWithTag:(int)x
- { return [self border:MISC_ROW_BORDER findSlotWithTag:x]; }
-
-
- - findCell:cell row:(int*)row col:(int*)col
- {
- int const NRows = [self numRows];
- int const NCols = [self numCols];
- for (int r = 0; r < NRows; r++)
- for (int c = 0; c < NCols; c++)
- if ([self cellAt:r:c] == cell)
- {
- *row = r;
- *col = c;
- return self;
- }
- *row = -1;
- *col = -1;
- return 0;
- }
-
- - findCellWithTag:(int)x row:(int*)row col:(int*)col
- {
- int const NRows = [self numRows];
- int const NCols = [self numCols];
- for (int r = 0; r < NRows; r++)
- for (int c = 0; c < NCols; c++)
- {
- id const cell = [self cellAt:r:c];
- if (cell && [cell respondsTo:@selector(tag)] && [cell tag] == x)
- {
- *row = r;
- *col = c;
- return cell;
- }
- }
- *row = -1;
- *col = -1;
- return 0;
- }
-
- - findCellWithTag:(int)x
- {
- int r, c;
- return [self findCellWithTag:x row:&r col:&c];
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Selection stuff
- //-----------------------------------------------------------------------------
- - (MiscSelectionMode) selectionMode { return mode; }
- - (void) setSelectionMode:(MiscSelectionMode) x
- {
- if (x != mode)
- {
- mode = x;
- [colInfo.view setSelectionMode: mode];
- [rowInfo.view setSelectionMode: mode];
- [tableView setSelectionMode: mode];
- }
- }
-
- - selectedCell { return 0; } // FIXME: write this
-
- - (BOOL) borderHasSelection: (MiscBorderType)b
- { return info[b]->border->hasSelection(); }
- - (BOOL) hasRowSelection { return [self borderHasSelection:MISC_ROW_BORDER]; }
- - (BOOL) hasColSelection { return [self borderHasSelection:MISC_COL_BORDER]; }
-
- - (BOOL) borderHasMultipleSelection: (MiscBorderType)b
- { return info[b]->border->hasMultipleSelection(); }
- - (BOOL) hasMultipleRowSelection
- { return [self borderHasMultipleSelection: MISC_ROW_BORDER]; }
- - (BOOL) hasMultipleColSelection
- { return [self borderHasMultipleSelection: MISC_COL_BORDER]; }
-
- - (unsigned int) borderNumSelectedSlots: (MiscBorderType)b
- { return info[b]->border->numSelected(); }
- - (unsigned int) numSelectedRows
- { return [self borderNumSelectedSlots: MISC_ROW_BORDER]; }
- - (unsigned int) numSelectedCols
- { return [self borderNumSelectedSlots: MISC_COL_BORDER]; }
-
- - (BOOL) border: (MiscBorderType)b slotIsSelected:(MiscCoord_P)slot
- { return info[b]->border->slotIsSelected( slot ); }
- - (BOOL) rowIsSelected:(MiscCoord_P)row
- { return [self border:MISC_ROW_BORDER slotIsSelected:row]; }
- - (BOOL) colIsSelected:(MiscCoord_P)col
- { return [self border:MISC_COL_BORDER slotIsSelected:col]; }
- - (BOOL) cellIsSelected:(MiscCoord_P)r :(MiscCoord_P)c
- { return ([self rowIsSelected:r] || [self colIsSelected:c]); }
-
- - (MiscCoord_P) borderSelectedSlot: (MiscBorderType)b
- { return info[b]->border->selectedSlot(); }
- - (MiscCoord_P) selectedRow
- { return [self borderSelectedSlot:MISC_ROW_BORDER]; }
- - (MiscCoord_P) selectedCol
- { return [self borderSelectedSlot:MISC_COL_BORDER]; }
-
- - (void) border: (MiscBorderType)b selectedTags: (MiscIntList*)tags
- { info[b]->border->selectedTags( tags ); }
- - (void) selectedRowTags: (MiscIntList*) tags
- { [self border:MISC_ROW_BORDER selectedTags:tags]; }
- - (void) selectedColTags: (MiscIntList*) tags
- { [self border:MISC_COL_BORDER selectedTags:tags]; }
-
- - (void) border: (MiscBorderType)b selectedSlots: (MiscIntList*)slots
- { info[b]->border->selectedSlots( slots ); }
- - (void) selectedRows: (MiscIntList*) rows
- { [self border:MISC_ROW_BORDER selectedSlots:rows]; }
- - (void) selectedCols: (MiscIntList*) cols
- { [self border:MISC_COL_BORDER selectedSlots:cols]; }
-
- - (void) selectionChanged
- {
- if ([self isAutodisplay] && [self canDraw])
- [self reflectSelection];
- else
- [self setNeedsDisplay:YES];
- }
-
- - (void) border: (MiscBorderType)b selectSlot:(MiscCoord_P)slot
- {
- BOOL changed = NO;
- MiscTableBorder* const bp = info[b]->border;
- unsigned int const n = bp->numSelected();
- if (0 <= slot && slot < bp->count())
- {
- if (n != 1 || bp->selectedSlot() != slot)
- {
- bp->selectSlot( slot );
- changed = YES;
- }
- }
- else
- {
- if (n > 0)
- {
- bp->selectNone();
- changed = YES;
- }
- }
- if (changed)
- [self selectionChanged];
- }
- - (void) selectRow:(MiscCoord_P)row
- { [self border:MISC_ROW_BORDER selectSlot:row]; }
- - (void) selectCol:(MiscCoord_P)col
- { [self border:MISC_COL_BORDER selectSlot:col]; }
-
- - (void) border: (MiscBorderType)b selectTags: (MiscIntList*)tags
- {
- info[b]->border->selectTags( tags );
- [self selectionChanged];
- }
- - (void) selectRowTags: (MiscIntList*) tags
- { [self border:MISC_ROW_BORDER selectTags:tags]; }
- - (void) selectColTags: (MiscIntList*) tags
- { [self border:MISC_COL_BORDER selectTags:tags]; }
-
- - (void) border: (MiscBorderType)b selectSlots: (MiscIntList*)slots
- {
- info[b]->border->selectSlots( slots );
- [self selectionChanged];
- }
- - (void) selectRows: (MiscIntList*) rows
- { [self border:MISC_ROW_BORDER selectSlots:rows]; }
- - (void) selectCols: (MiscIntList*) cols;
- { [self border:MISC_COL_BORDER selectSlots:cols]; }
-
- - (void) borderSelectAll: (MiscBorderType)b
- {
- if (mode == MISC_LIST_MODE || mode == MISC_HIGHLIGHT_MODE)
- {
- info[b]->border->selectAll();
- [self selectionChanged];
- }
- }
- - (void) selectAllRows { [self borderSelectAll: MISC_ROW_BORDER]; }
- - (void) selectAllCols { [self borderSelectAll: MISC_COL_BORDER]; }
- - selectAll:sender
- {
- [self selectAllRows];
- [self sendActionIfEnabled];
- return self;
- }
-
- - (void) borderClearSelection: (MiscBorderType)b
- {
- info[b]->border->selectNone();
- [self selectionChanged];
- }
- - (void) clearRowSelection { [self borderClearSelection: MISC_ROW_BORDER]; }
- - (void) clearColSelection { [self borderClearSelection: MISC_COL_BORDER]; }
- - (void) clearSelection { [self clearRowSelection]; [self clearColSelection]; }
-
-
- //-----------------------------------------------------------------------------
- // Keyboard cursor stuff
- //-----------------------------------------------------------------------------
- - (void) reflectCursor { [tableView reflectCursor]; }
- - (MiscCoord_P) borderCursor: (MiscBorderType)b
- { return info[b]->border->getCursor_P(); }
- - (MiscCoord_P) cursorRow { return [self borderCursor: MISC_ROW_BORDER]; }
- - (MiscCoord_P) cursorCol { return [self borderCursor: MISC_COL_BORDER]; }
-
- - (void) border: (MiscBorderType)b setCursor: (MiscCoord_P) slot
- { info[b]->border->setCursor_P( slot ); [self reflectCursor]; }
- - (void) setCursorRow: (MiscCoord_P) row
- { [self border: MISC_ROW_BORDER setCursor: row]; }
- - (void) setCursorCol: (MiscCoord_P) col
- { [self border: MISC_COL_BORDER setCursor: col]; }
-
- - (void) borderClearCursor: (MiscBorderType)b
- { info[b]->border->clearCursor(); [self reflectCursor]; }
- - (void) clearCursorRow { [self borderClearCursor: MISC_ROW_BORDER]; }
- - (void) clearCursorCol { [self borderClearCursor: MISC_COL_BORDER]; }
- - (void) clearCursor { [self clearCursorRow]; [self clearCursorCol]; }
-
- - (BOOL) borderHasValidCursor: (MiscBorderType)b
- { return info[b]->border->hasValidCursor(); }
- - (BOOL) hasValidCursorRow
- { return [self borderHasValidCursor: MISC_ROW_BORDER]; }
- - (BOOL) hasValidCursorCol
- { return [self borderHasValidCursor: MISC_COL_BORDER]; }
-
-
- //-----------------------------------------------------------------------------
- // Overrides... Scrollers are always required.
- //-----------------------------------------------------------------------------
- - setHorizScrollerRequired: (BOOL) flag { return self; }
- - setVertScrollerRequired: (BOOL) flag { return self; }
-
-
- //-----------------------------------------------------------------------------
- // - getDocClipFrame:
- //-----------------------------------------------------------------------------
- - (void) getDocClipFrame: (NXRect*) rect
- {
- [contentView getFrame: rect];
- }
-
-
- //-----------------------------------------------------------------------------
- // - freeBorder:
- //-----------------------------------------------------------------------------
- - (void) freeBorder:(MiscBorderInfo*)p
- {
- [p->view removeFromSuperview];
- [p->view free];
- [p->clip removeFromSuperview];
- [p->clip free];
- delete p->border;
- }
-
-
- //-----------------------------------------------------------------------------
- // - free
- //-----------------------------------------------------------------------------
- - free
- {
- [self setAutodisplay:NO]; // Don't do any drawing!
- [self emptyAndFreeCells];
- [self freeBorder:&colInfo];
- [self freeBorder:&rowInfo];
- [nullView removeFromSuperview];
- [nullView free];
- [tableView removeFromSuperview];
- [tableView free];
- return [super free];
- }
-
-
- //-----------------------------------------------------------------------------
- // get/set min/max total size limits.
- //-----------------------------------------------------------------------------
- - (NXCoord) totalSize:(MiscBorderType)b
- { return (NXCoord) info[b]->border->totalSize(); }
- - (NXCoord) totalWidth
- { return [self totalSize:MISC_COL_BORDER]; }
- - (NXCoord) totalHeight
- { return [self totalSize:MISC_ROW_BORDER]; }
-
- - (NXCoord) minTotalSize:(MiscBorderType)b
- { return (NXCoord) info[b]->border->getMinTotalSize(); }
- - (NXCoord) maxTotalSize:(MiscBorderType)b
- { return (NXCoord) info[b]->border->getMaxTotalSize(); }
- - (NXCoord) minTotalWidth
- { return [self minTotalSize:MISC_COL_BORDER]; }
- - (NXCoord) maxTotalWidth
- { return [self maxTotalSize:MISC_COL_BORDER]; }
- - (NXCoord) minTotalHeight
- { return [self minTotalSize:MISC_ROW_BORDER]; }
- - (NXCoord) maxTotalHeight
- { return [self maxTotalSize:MISC_ROW_BORDER]; }
-
- // FIXME: Need to decide whether or not to update the views here.
- // FIXME: Should check current value before setting.
- - (void) border:(MiscBorderType)b setMinTotalSize:(NXCoord)size
- { info[b]->border->setMinTotalSize( (MiscPixels)floor(size) ); }
- - (void) border:(MiscBorderType)b setMaxTotalSize:(NXCoord)size
- { info[b]->border->setMaxTotalSize( (MiscPixels)floor(size) ); }
- - (void) setMinTotalWidth:(NXCoord)size
- { [self border:MISC_COL_BORDER setMinTotalSize:size]; }
- - (void) setMaxTotalWidth:(NXCoord)size
- { [self border:MISC_COL_BORDER setMaxTotalSize:size]; }
- - (void) setMinTotalHeight:(NXCoord)size
- { [self border:MISC_ROW_BORDER setMinTotalSize:size]; }
- - (void) setMaxTotalHeight:(NXCoord)size
- { [self border:MISC_ROW_BORDER setMaxTotalSize:size]; }
-
-
- //-----------------------------------------------------------------------------
- // - constrainSize
- //-----------------------------------------------------------------------------
- - (void) constrainSize
- {
- NXRect r;
- [self getDocClipFrame: &r];
- if ([self minTotalSizeIsConstrained:MISC_COL_BORDER])
- [self border:MISC_COL_BORDER setMinTotalSize: r.size.width];
- if ([self maxTotalSizeIsConstrained:MISC_COL_BORDER])
- [self border:MISC_COL_BORDER setMaxTotalSize: r.size.width];
- if ([self minTotalSizeIsConstrained:MISC_ROW_BORDER])
- [self border:MISC_ROW_BORDER setMinTotalSize: r.size.height];
- if ([self maxTotalSizeIsConstrained:MISC_ROW_BORDER])
- [self border:MISC_ROW_BORDER setMaxTotalSize: r.size.height];
- [rowInfo.view adjustSize];
- [colInfo.view adjustSize];
- [tableView adjustSize];
- }
-
-
- //-----------------------------------------------------------------------------
- // - sizeToCells
- //-----------------------------------------------------------------------------
- - sizeToCells
- {
- [self constrainSize];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // get/set min/max constrained
- //-----------------------------------------------------------------------------
- - (BOOL) minTotalSizeIsConstrained:(MiscBorderType)b
- { return info[b]->constrain_min; }
- - (BOOL) maxTotalSizeIsConstrained:(MiscBorderType)b
- { return info[b]->constrain_max; }
- - (BOOL) minTotalWidthIsConstrained
- { return [self minTotalSizeIsConstrained:MISC_COL_BORDER]; }
- - (BOOL) maxTotalWidthIsConstrained
- { return [self maxTotalSizeIsConstrained:MISC_COL_BORDER]; }
- - (BOOL) minTotalHeightIsConstrained
- { return [self minTotalSizeIsConstrained:MISC_ROW_BORDER]; }
- - (BOOL) maxTotalHeightIsConstrained
- { return [self maxTotalSizeIsConstrained:MISC_ROW_BORDER]; }
-
- - (void) border:(MiscBorderType)b constrainMinTotalSize:(BOOL)flag;
- {
- MiscBorderInfo* ip = info[b];
- if (ip->constrain_min != flag)
- {
- ip->constrain_min = flag;
- if (!flag)
- [self border:MISC_COL_BORDER setMinTotalSize:0];
- [self constrainSize];
- }
- }
-
- - (void) border:(MiscBorderType)b constrainMaxTotalSize:(BOOL)flag
- {
- MiscBorderInfo* ip = info[b];
- if (ip->constrain_max != flag)
- {
- ip->constrain_max = flag;
- if (!flag)
- [self border:MISC_COL_BORDER
- setMaxTotalSize: (NXCoord) MISC_MAX_PIXELS_SIZE ];
- [self constrainSize];
- }
- }
-
- - (void) constrainMinTotalWidth:(BOOL)flag
- { [self border:MISC_COL_BORDER constrainMinTotalSize:flag]; }
- - (void) constrainMaxTotalWidth:(BOOL)flag
- { [self border:MISC_COL_BORDER constrainMaxTotalSize:flag]; }
- - (void) constrainMinTotalHeight:(BOOL)flag
- { [self border:MISC_ROW_BORDER constrainMinTotalSize:flag]; }
- - (void) constrainMaxTotalHeight:(BOOL)flag
- { [self border:MISC_ROW_BORDER constrainMaxTotalSize:flag]; }
-
-
- //-----------------------------------------------------------------------------
- // - sizeTo::
- //-----------------------------------------------------------------------------
- - sizeTo:(NXCoord)width :(NXCoord)height
- {
- [super sizeTo:width:height];
- [self constrainSize];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - forwardBGColor
- //-----------------------------------------------------------------------------
- - (void) forwardBGColor
- {
- [super setBackgroundColor: backgroundColor];
- [colInfo.clip setBackgroundColor: backgroundColor];
- [rowInfo.clip setBackgroundColor: backgroundColor];
- }
-
-
- //-----------------------------------------------------------------------------
- // - initBorder:type:
- //-----------------------------------------------------------------------------
- - (void) initBorder:(MiscBorderInfo*) p type:(MiscBorderType) type
- {
- NXZone* const z = [self zone];
- if (p->border == 0)
- p->border = new( NXZoneMalloc(z,sizeof(*(p->border))) )
- MiscTableBorder( type );
- p->border->setOwner( self );
-
- if (type == MISC_COL_BORDER)
- p->view = [[MiscColView allocFromZone:z]
- initFrame:0 scroll:self info:p->border];
- else
- p->view = [[MiscRowView allocFromZone:z]
- initFrame:0 scroll:self info:p->border];
-
- p->clip = [[ClipView allocFromZone:z] initFrame:0];
- [p->clip setDocView:p->view];
- if (p->isOn)
- {
- [self addSubview: p->clip];
- [window invalidateCursorRectsForView: p->view];
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - doInit:
- //
- // NOTE *1*: The tableView was initialized with an argument of 0 so it's
- // frame is invalid. Calling constrainSize with an invalid frame
- // can result in crashers when it tries to access slots outside
- // of the appropriate area. Calling -tile first ensures that the
- // frame is valid.
- //-----------------------------------------------------------------------------
- - (void) doInit:(int)ver
- {
- [window disableDisplay];
- [self setBorderType: NX_BEZEL];
- [super setHorizScrollerRequired: YES];
- [super setVertScrollerRequired: YES];
-
- info[ MISC_COL_BORDER ] = &colInfo;
- info[ MISC_ROW_BORDER ] = &rowInfo;
-
- [self initBorder:&colInfo type:MISC_COL_BORDER];
- [self initBorder:&rowInfo type:MISC_ROW_BORDER];
-
- NXZone* const z = [self zone];
-
- tableView = [[MiscTableView allocFromZone:z] initFrame:0
- scroll:self
- colInfo:colInfo.border
- rowInfo:rowInfo.border];
-
- nullView = [[MiscNullView allocFromZone:z] initFrame:0];
-
- if (colInfo.isOn && rowInfo.isOn)
- [self addSubview:nullView];
-
- id oldView = [self setDocView: tableView];
- [oldView free];
- [self tile]; // NOTE *1*
- [self constrainSize];
- [self forwardBGColor];
-
- [self registerServicesTypes];
- [window reenableDisplay];
- }
-
-
- //-----------------------------------------------------------------------------
- // - initFrame:
- //-----------------------------------------------------------------------------
- - initFrame: (NXRect const*) frameRect
- {
- [super initFrame: frameRect];
- font = [[self class] defaultFont];
- tag = 0;
- enabled = YES;
- colInfo.border = 0; colInfo.isOn = YES;
- colInfo.constrain_min = YES;
- colInfo.constrain_max = NO;
- rowInfo.border = 0; rowInfo.isOn = NO;
- rowInfo.constrain_min = YES;
- rowInfo.constrain_max = NO;
- textColor = [[self class] defaultTextColor];
- backgroundColor = [[self class] defaultBackgroundColor];
- highlightTextColor = [[self class] defaultHighlightTextColor];
- highlightBackgroundColor = [[self class] defaultHighlightBackgroundColor];
-
- [self doInit:MISC_TS_VERSION];
-
- if ([self respondsTo:@selector(initIB)]) [self perform:@selector(initIB)];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - setFrame:
- //-----------------------------------------------------------------------------
- - setFrame: (NXRect const*) frameRect
- {
- [super setFrame:frameRect];
- [self constrainSize];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - adjustSizes
- //-----------------------------------------------------------------------------
- - (void) adjustSizes
- {
- if (colInfo.isOn && colInfo.view != 0)
- [colInfo.view adjustSize];
- if (rowInfo.isOn && rowInfo.view != 0)
- [rowInfo.view adjustSize];
- [tableView adjustSize];
- }
-
-
- //-----------------------------------------------------------------------------
- // - tile
- //-----------------------------------------------------------------------------
- - tile
- {
- [window disableDisplay];
- [super tile];
- [self adjustSizes];
-
- if (colInfo.isOn && !rowInfo.isOn)
- {
- NXCoord colHeight = [colInfo.view frameHeight];
- NXRect colRect;
- NXRect docRect;
-
- [contentView getFrame: &docRect];
-
- NXDivideRect( &docRect, &colRect, colHeight, NX_YMIN );
-
- [colInfo.clip setFrame: &colRect];
- [contentView setFrame: &docRect];
- [window invalidateCursorRectsForView: colInfo.view];
- }
- else if (!colInfo.isOn && rowInfo.isOn)
- {
- NXCoord rowWidth = [rowInfo.view frameHeight];
- NXRect rowRect;
- NXRect docRect;
-
- [contentView getFrame: &docRect];
-
- NXDivideRect( &docRect, &rowRect, rowWidth, NX_XMIN );
-
- [rowInfo.clip setFrame: &rowRect];
- [contentView setFrame: &docRect];
- [window invalidateCursorRectsForView: rowInfo.view];
- }
- else if (colInfo.isOn && rowInfo.isOn)
- {
- NXCoord colHeight = [colInfo.view frameHeight];
- NXCoord rowWidth = [rowInfo.view frameHeight];
- NXRect nulRect;
- NXRect colRect;
- NXRect rowRect;
- NXRect docRect;
-
- [contentView getFrame: &docRect];
-
- NXDivideRect( &docRect, &colRect, colHeight, NX_YMIN );
- NXDivideRect( &colRect, &nulRect, rowWidth, NX_XMIN );
- NXDivideRect( &docRect, &rowRect, rowWidth, NX_XMIN );
-
- [nullView setFrame: &nulRect];
- [colInfo.clip setFrame: &colRect];
- [rowInfo.clip setFrame: &rowRect];
- [contentView setFrame: &docRect];
- [window invalidateCursorRectsForView: colInfo.view];
- [window invalidateCursorRectsForView: rowInfo.view];
- }
-
- [window reenableDisplay];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - reflectScroll:
- //-----------------------------------------------------------------------------
- - reflectScroll: aView
- {
- if (aView == contentView) // only reflect position of contentView
- [super reflectScroll: aView];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - scrollClip:to:
- //-----------------------------------------------------------------------------
- - scrollClip: aClipView to: (const NXPoint *) aPoint
- {
- if (aClipView == contentView) // contentView only.
- {
- NXRect rect;
- [window disableFlushWindow];
-
- [aClipView rawScroll: aPoint]; // Scroll content
-
- if (colInfo.isOn)
- {
- [colInfo.clip getBounds: &rect]; // Maybe scroll col headings.
- if (rect.origin.x != aPoint->x)
- {
- rect.origin.x = aPoint->x;
- [colInfo.clip rawScroll: &rect.origin];
- [window invalidateCursorRectsForView: colInfo.view];
- }
- }
-
- if (rowInfo.isOn)
- {
- [rowInfo.clip getBounds: &rect]; // Maybe scroll row labels.
- if (rect.origin.y != aPoint->y)
- {
- rect.origin.y = aPoint->y;
- [rowInfo.clip rawScroll: &rect.origin];
- [window invalidateCursorRectsForView: rowInfo.view];
- }
- }
-
- [[window reenableFlushWindow] flushWindow];
- }
- else if (aClipView == (id)colInfo.clip)
- {
- NXRect rect;
- [contentView getBounds: &rect];
- rect.origin.x = aPoint->x;
- [self scrollClip:contentView to:&(rect.origin)];
- [self reflectScroll:contentView];
- }
- else if (aClipView == (id)rowInfo.clip)
- {
- NXRect rect;
- [contentView getBounds: &rect];
- rect.origin.y = aPoint->y;
- [self scrollClip:contentView to:&(rect.origin)];
- [self reflectScroll:contentView];
- }
- return self;
- }
-
-
-
- //-----------------------------------------------------------------------------
- // Delegate Stuff
- //-----------------------------------------------------------------------------
- - delegate { return delegate; }
- - setDelegate:obj { delegate = obj; return self; }
- - dataDelegate { return dataDelegate; }
- - setDataDelegate:obj { dataDelegate = obj; return self; }
-
- - (char const*) border:(MiscBorderType)b getDelegateSlotTitle:(int)slot
- {
- if (delegate != 0 &&
- [delegate respondsTo:@selector(tableScroll:border:slotTitle:)])
- return [delegate tableScroll:self border:b slotTitle:slot];
-
- if (dataDelegate != 0 &&
- [dataDelegate respondsTo:@selector(tableScroll:border:slotTitle:)])
- return [dataDelegate tableScroll:self border:b slotTitle:slot];
-
- return 0;
- }
-
- - border:(MiscBorderType)b getDelegateSlotPrototype:(int)s
- {
- if (delegate != 0 &&
- [delegate respondsTo:@selector(tableScroll:border:slotPrototype:)])
- return [delegate tableScroll:self border:b slotPrototype:s];
-
- if (dataDelegate != 0 &&
- [dataDelegate respondsTo:@selector(tableScroll:border:slotPrototype:)])
- return [dataDelegate tableScroll:self border:b slotPrototype:s];
-
- return 0;
- }
-
- - (void) border:(MiscBorderType)b slotDraggedFrom:(int)fromPos to:(int)toPos
- {
- MiscBorderType const ob = otherBorder(b);
- if ([self autoSortSlots:ob])
- {
- int slot = [self border:b slotAtPosition:toPos];
- if ([self border:b slotSortType:slot] != MISC_SORT_SKIP ||
- [self border:b slotSortFunc:slot] != 0)
- [self sortSlots:ob]; // Don't resort if it doesn't affect ordering.
- }
- if (delegate != 0 &&
- [delegate respondsTo:@selector(tableScroll:border:slotDraggedFrom:to:)])
- [delegate tableScroll:self border:b slotDraggedFrom:fromPos to:toPos];
- }
-
- - (void) border:(MiscBorderType)b slotResized:(int)n
- {
- if (delegate != 0 &&
- [delegate respondsTo:@selector(tableScroll:border:slotResized:)])
- [delegate tableScroll:self border:b slotResized:n];
- }
-
-
- //-----------------------------------------------------------------------------
- // Target / Action
- //-----------------------------------------------------------------------------
- - target { return target; }
- - setTarget:obj { target = obj; return self; }
- - doubleTarget { return doubleTarget; }
- - setDoubleTarget:obj { doubleTarget = obj; return self; }
- - (SEL) action { return action; }
- - setAction:(SEL)new_sel { action = new_sel; return self; }
- - setDoubleAction:(SEL)new_sel { doubleAction = new_sel; return self; }
- - (SEL) doubleAction { return doubleAction; }
-
- - sendAction:(SEL)aSel to:obj
- {
- if (aSel == 0)
- aSel = action;
- if (obj == 0)
- obj = target;
- return ([NXApp sendAction:aSel to:obj from:self] ? self : 0);
- }
-
- - (SEL) getCellAction:cell
- {
- if ([cell respondsTo:@selector(action)])
- return [cell action];
- return 0;
- }
-
- - getCellTarget:cell
- {
- if ([cell respondsTo:@selector(target)])
- return [cell target];
- return 0;
- }
-
- - sendAction
- {
- id cell = [self selectedCell];
- return [self sendAction:[self getCellAction:cell]
- to:[self getCellTarget:cell]];
- }
-
- - sendDoubleAction
- {
- return [self sendAction:doubleAction to:doubleTarget];
- }
-
- - sendActionIfEnabled
- {
- if ([self isEnabled])
- return [self sendAction];
- return 0;
- }
-
- - sendDoubleActionIfEnabled
- {
- if ([self isEnabled])
- return [self sendDoubleAction];
- return 0;
- }
-
-
- //-----------------------------------------------------------------------------
- // FONT
- //-----------------------------------------------------------------------------
- + (Font*) defaultFont
- {
- return [Font userFontOfSize:12.0 matrix:NX_FLIPPEDMATRIX];
- }
-
- - font
- {
- return font;
- }
-
-
- static double get_height( Font* font )
- {
- NXFontMetrics const* const p = [font metrics];
- double const size = [font pointSize];
- return ((p->fontBBox[3] - p->fontBBox[1]) * size);
- }
-
-
- - setFont:newFont
- {
- if (newFont != 0 && newFont != (id)font && [newFont isKindOf:[Font class]])
- {
- [window disableDisplay];
- Font* oldFont = font;
- font = newFont;
- NXCoord old_size = [self uniformSizeRows];
- if (old_size != 0)
- {
- // FIXME: Handle this better. Different cell-types will have
- // different amounts of "fixed-size" border stuff.
- NXCoord const BORDER_THICKNESS = 1;
- old_size -= BORDER_THICKNESS;
- NXCoord const new_size =
- floor( 0.5 + (double(old_size) *
- (get_height( newFont ) / get_height( oldFont ))));
- if (new_size != old_size)
- [self setUniformSizeRows:(new_size + BORDER_THICKNESS)];
- }
- // FIXME: Set font in all existing prototype cells.
- // WARNING: Currently, just asking the border for a prototype
- // in a given slot allocates and initializes an array of prototypes.
- if (![self isLazy]) // Eager beaver sets all cells now.
- {
- int const NRows = num_rows;
- int const NCols = num_cols;
- for (int r = 0; r < NRows; r++)
- {
- for (int c = 0; c < NCols; c++)
- {
- id cell = [self cellAt:r:c];
- if (cell != 0)
- {
- if ([cell respondsTo:@selector(setOwnerFont:)])
- [cell setOwnerFont:newFont];
- else if ([cell respondsTo:@selector(setFont:)])
- [cell setFont:newFont];
- }
- }
- }
- }
- if (delegate != 0 &&
- [delegate respondsTo:@selector(tableScroll:fontChangedFrom:to:)])
- [delegate tableScroll:self fontChangedFrom:oldFont to:newFont];
- if (dataDelegate != 0 &&
- [dataDelegate respondsTo:
- @selector(tableScroll:fontChangedFrom:to:)])
- [dataDelegate tableScroll:self fontChangedFrom:oldFont to:newFont];
-
- [window reenableDisplay];
- [self update];
- }
- return self;
- }
-
-
- - changeFont:sender
- {
- FontManager* fontMgr = [FontManager new];
- Font* newFont = [fontMgr convertFont:[fontMgr selFont]];
- if (newFont != 0 && newFont != font)
- {
- [window disableDisplay];
- Font* oldFont = font;
- [self setFont:newFont];
- if (delegate != 0 &&
- [delegate respondsTo: @selector(tableScroll:changeFont:to:)])
- [delegate tableScroll:self changeFont:oldFont to:newFont];
- if (dataDelegate != 0 &&
- [dataDelegate respondsTo: @selector(tableScroll:changeFont:to:)])
- [dataDelegate tableScroll:self changeFont:oldFont to:newFont];
- [window reenableDisplay];
- [self update];
- }
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // COLOR
- //
- // The following macros expand into the implementations for these functions.
- // Their names are listed so they can be found when searched for.
- // setBackgroundColor:, setTextColor:,
- // setHighlightBackgroundColor:, setHighlightTextColor:
- // setBackgroundGray:, setTextGray:,
- // setHighlightBackgroundGray:, setHighlightTextGray:
- // backgroundGray:, textGray:, highlightBackgroundGray:, highlightTextGray:
- //-----------------------------------------------------------------------------
- + (NXColor) defaultBackgroundColor { return NX_COLORLTGRAY; }
- + (NXColor) defaultTextColor { return NX_COLORBLACK; }
- + (NXColor) defaultHighlightBackgroundColor { return NX_COLORWHITE; }
- + (NXColor) defaultHighlightTextColor { return NX_COLORBLACK; }
-
- - (NXColor) backgroundColor { return backgroundColor; }
- - (NXColor) textColor { return textColor; }
- - (NXColor) highlightBackgroundColor { return highlightBackgroundColor; }
- - (NXColor) highlightTextColor { return highlightTextColor; }
-
- - setColor:(NXColor) value { return [self setBackgroundColor:value]; }
- - (NXColor) color { return [self backgroundColor]; }
-
- - setColor:(NXColor)x // New color value.
- var:(NXColor*)v // Instance variable for the color.
- sel1:(SEL)sel1 // "setOwner...Color:" message for cell.
- sel2:(SEL)sel2 // "set...Color:" message for cell.
- notifySel:(SEL)notifySel // "..ColorChangedTo:" message
- {
- if (!NXEqualColor( x, *v ))
- {
- BOOL const was_auto = [self isAutodisplay];
- [self setAutodisplay:NO];
-
- *v = x;
- if (v == &backgroundColor) [self forwardBGColor];
-
- if (![self isLazy])
- {
- int const NRows = num_rows;
- int const NCols = num_cols;
- for (int r = 0; r < NRows; r++)
- for (int c = 0; c < NCols; c++)
- {
- id cell = [self cellAt:r:c];
- if (cell != 0)
- {
- if ([cell respondsTo:sel1])
- (*[cell methodFor:sel1])( cell, sel1, x );
- else if ([cell respondsTo:sel2])
- (*[cell methodFor:sel2])( cell, sel2, x );
- }
- }
- }
-
- if (delegate != 0 && [delegate respondsTo:notifySel])
- (*[delegate methodFor:notifySel])( delegate, notifySel, self, x );
-
- if (dataDelegate != 0 && [dataDelegate respondsTo:notifySel])
- (*[dataDelegate methodFor:notifySel])
- ( dataDelegate, notifySel, self, x );
-
- [self setNeedsDisplay:YES];
- [self setAutodisplay:was_auto]; // Will display if needed.
- }
-
- return self;
- }
-
-
- #define MISC_SET_COLOR_FUNC(LNAME,CNAME)\
- - set##CNAME##Color: (NXColor) value\
- { return [self setColor:value\
- var:& LNAME##Color\
- sel1:@selector(setOwner##CNAME##Color:)\
- sel2:@selector(set##CNAME##Color:)\
- notifySel:@selector(tableScroll:LNAME##ColorChangedTo:)]; }
-
- MISC_SET_COLOR_FUNC( background, Background )
- MISC_SET_COLOR_FUNC( text, Text )
- MISC_SET_COLOR_FUNC( highlightBackground, HighlightBackground )
- MISC_SET_COLOR_FUNC( highlightText, HighlightText )
- #undef MISC_SET_COLOR_FUNC
-
-
- static inline float color_to_gray( NXColor x )
- {
- float gray;
- NXConvertColorToGray( x, &gray );
- return gray;
- }
-
-
- #define MISC_GET_GRAY_FUNC( LNAME )\
- - (float) LNAME##Gray { return color_to_gray( [self LNAME##Color] ); }
-
- MISC_GET_GRAY_FUNC( background )
- MISC_GET_GRAY_FUNC( text )
- MISC_GET_GRAY_FUNC( highlightBackground )
- MISC_GET_GRAY_FUNC( highlightText )
- #undef MISC_GET_GRAY_FUNC
-
- #define MISC_SET_GRAY_FUNC( CNAME )\
- - set##CNAME##Gray: (float) x\
- { return [self set##CNAME##Color: NXConvertGrayToColor(x)]; }
-
- MISC_SET_GRAY_FUNC( Background )
- MISC_SET_GRAY_FUNC( Text )
- MISC_SET_GRAY_FUNC( HighlightBackground )
- MISC_SET_GRAY_FUNC( HighlightText )
- #undef MISC_SET_GRAY_FUNC
-
-
- //-----------------------------------------------------------------------------
- // SAVE / RESTORE
- //-----------------------------------------------------------------------------
-
- - border:(MiscBorderType)b slotOrder:(MiscIntList*)list
- {
- if (list != 0)
- {
- MiscTableBorder const* const bp = info[b]->border;
- MiscCoord_P const* const vmap = bp->getVMap();
- int const lim = bp->count();
- [list empty];
- for (int i = 0; i < lim; i++)
- [list addInt: (vmap ? vmap[i] : i) ];
- return self;
- }
- return 0;
- }
- - colOrder:(MiscIntList*)list
- { return [self border:MISC_COL_BORDER slotOrder:list]; }
- - rowOrder:(MiscIntList*)list
- { return [self border:MISC_ROW_BORDER slotOrder:list]; }
-
- - border:(MiscBorderType)b setSlotOrder:(MiscIntList*)list
- {
- id retval = 0;
- if (list != 0)
- {
- MiscTableBorder* const bp = info[b]->border;
- int const lim = bp->count();
- if ([list count] == lim)
- if (bp->setVMap( [list rawData] ))
- {
- MiscBorderType const ob = otherBorder(b);
- if ([self autoSortSlots:ob])
- [self sortSlots:ob];
- retval = self;
- }
- }
- return retval;
- }
- - setColOrder:(MiscIntList*)list
- { return [self border:MISC_COL_BORDER setSlotOrder:list]; }
- - setRowOrder:(MiscIntList*)list
- { return [self border:MISC_ROW_BORDER setSlotOrder:list]; }
-
- - (char*) border:(MiscBorderType)b slotOrderAsString:(char*)buff
- size:(int)buff_size canExpand:(BOOL)canExpand
- {
- char* retval;
- MiscIntList* list = [[MiscIntList alloc] init];
- [self border:b slotOrder:list];
- retval = [list writeToString:buff size:buff_size canExpand:canExpand];
- [list free];
- return retval;
- }
- - (char*) colOrderAsString:(char*)buff
- size:(int)buff_size canExpand:(BOOL)canExpand
- { return [self border:MISC_COL_BORDER slotOrderAsString:buff
- size:buff_size canExpand:canExpand]; }
- - (char*) rowOrderAsString:(char*)buff
- size:(int)buff_size canExpand:(BOOL)canExpand
- { return [self border:MISC_ROW_BORDER slotOrderAsString:buff
- size:buff_size canExpand:canExpand]; }
-
- - border:(MiscBorderType)b setSlotOrderFromString:(char const*)s
- {
- id retval;
- MiscIntList* list = [[MiscIntList alloc] init];
- [list readFromString:s];
- retval = [self border:b setSlotOrder:list];
- [list free];
- return retval;
- }
- - setColOrderFromString:(char const*)s
- { return [self border:MISC_COL_BORDER setSlotOrderFromString:s]; }
- - setRowOrderFromString:(char const*)s
- { return [self border:MISC_ROW_BORDER setSlotOrderFromString:s]; }
-
-
- - border:(MiscBorderType)b slotSizes:(MiscIntList*)list
- {
- if (list != 0)
- {
- MiscTableBorder const* const bp = info[b]->border;
- int const lim = bp->count();
- [list empty];
- for (int i = 0; i < lim; i++)
- [list addInt: (int) bp->getSize_P( i ) ];
- return self;
- }
- return 0;
- }
- - colSizes:(MiscIntList*)list
- { return [self border:MISC_COL_BORDER slotSizes:list]; }
- - rowSizes:(MiscIntList*)list
- { return [self border:MISC_ROW_BORDER slotSizes:list]; }
-
- - border:(MiscBorderType)b setSlotSizes:(MiscIntList*)list
- {
- if (list != 0)
- {
- MiscTableBorder* const bp = info[b]->border;
- int const lim = bp->count();
- if ([list count] == lim)
- {
- for (int i = 0; i < lim; i++)
- bp->setSize_P( i, (MiscPixels) [list intAt:i] );
- [self constrainSize];
- return self;
- }
- }
- return 0;
- }
- - setColSizes:(MiscIntList*)list
- { return [self border:MISC_COL_BORDER setSlotSizes:list]; }
- - setRowSizes:(MiscIntList*)list
- { return [self border:MISC_ROW_BORDER setSlotSizes:list]; }
-
- - (char*) border:(MiscBorderType)b slotSizesAsString:(char*)buff
- size:(int)buff_size canExpand:(BOOL)canExpand
- {
- char* retval;
- MiscIntList* list = [[MiscIntList alloc] init];
- [self border:b slotSizes:list];
- retval = [list writeToString:buff size:buff_size canExpand:canExpand];
- [list free];
- return retval;
- }
- - (char*) colSizesAsString:(char*)buff
- size:(int)buff_size canExpand:(BOOL)canExpand
- { return [self border:MISC_COL_BORDER slotSizesAsString:buff
- size:buff_size canExpand:canExpand]; }
- - (char*) rowSizesAsString:(char*)buff
- size:(int)buff_size canExpand:(BOOL)canExpand
- { return [self border:MISC_ROW_BORDER slotSizesAsString:buff
- size:buff_size canExpand:canExpand]; }
-
- - border:(MiscBorderType)b setSlotSizesFromString:(char const*)s
- {
- id retval;
- MiscIntList* list = [[MiscIntList alloc] init];
- [list readFromString:s];
- retval = [self border:b setSlotSizes:list];
- [list free];
- return retval;
- }
- - setColSizesFromString:(char const*)s
- { return [self border:MISC_COL_BORDER setSlotSizesFromString:s]; }
- - setRowSizesFromString:(char const*)s
- { return [self border:MISC_ROW_BORDER setSlotSizesFromString:s]; }
-
-
-
- //-----------------------------------------------------------------------------
- // Border Views
- //-----------------------------------------------------------------------------
- - (BOOL) setBorder:(MiscBorderType)type on:(BOOL)on
- {
- MiscBorderInfo& b = *(info[type]);
- if (b.isOn != on)
- {
- BOOL const other_border_is_on = info[otherBorder(type)]->isOn;
- b.isOn = on;
- if (on)
- {
- [self addSubview: b.clip];
- [window invalidateCursorRectsForView: b.view];
- if (other_border_is_on)
- [self addSubview: nullView];
- }
- else
- {
- [b.clip removeFromSuperview];
- if (other_border_is_on)
- [nullView removeFromSuperview];
- }
- [self tile];
- [self constrainSize];
- [self update];
- return YES;
- }
- return NO;
- }
-
-
- //-----------------------------------------------------------------------------
- // SLOT methods
- //-----------------------------------------------------------------------------
- - (MiscTableBorder*) border:(MiscBorderType)b
- { return info[b]->border; }
- - (BOOL) border:(MiscBorderType)b setTitlesOn: (BOOL) on_off
- { return [self setBorder:b on:on_off]; }
- - (BOOL) borderTitlesOn:(MiscBorderType)b
- { return info[b]->isOn; }
- - (MiscTableTitleMode) borderTitleMode:(MiscBorderType)b
- { return info[b]->border->getTitleMode(); }
- - (void) border:(MiscBorderType)b setTitleMode:(MiscTableTitleMode)x
- {
- MiscBorderInfo* const ip = info[b];
- if (ip->border->setTitleMode(x) && ip->isOn && ip->border->count() > 0)
- [ip->view update];
- }
-
- - border:(MiscBorderType)b moveSlotFrom:(int)fromPos to:(int)toPos
- { info[b]->border->moveFromTo(fromPos,toPos); return self; }
- - (int) border:(MiscBorderType)b slotPosition:(int)n
- { return info[b]->border->physicalToVisual(n); }
- - (int) border:(MiscBorderType)b slotAtPosition:(int)n
- { return info[b]->border->visualToPhysical(n); }
-
- - (void) border:(MiscBorderType)b physicalToVisual:(MiscIntList*)list
- {
- for (unsigned int i = [list count]; i-- > 0; )
- {
- MiscCoord_P const p = [list intAt:i];
- [list replaceIntAt:i with:[self border:b slotPosition:p]];
- }
- }
-
- - (void) border:(MiscBorderType)b visualToPhysical:(MiscIntList*)list
- {
- for (unsigned int i = [list count]; i-- > 0; )
- {
- MiscCoord_V const v = [list intAt:i];
- [list replaceIntAt:i with:[self border:b slotAtPosition:v]];
- }
- }
-
-
- - (BOOL) sizeableSlots:(MiscBorderType)b
- { return info[b]->border->isSizeable(); }
- - (BOOL) draggableSlots:(MiscBorderType)b
- { return info[b]->border->isDraggable(); }
- - (BOOL) modifierDragSlots:(MiscBorderType)b
- { return info[b]->border->isModifierDrag(); }
- - (NXCoord) uniformSizeSlots:(MiscBorderType)b
- { return (NXCoord) info[b]->border->getUniformSize(); }
-
- - (NXCoord) border:(MiscBorderType)b slotAdjustedSize:(int)n
- { return (NXCoord) info[b]->border->effectiveSize_P(n); }
- - (NXCoord) border:(MiscBorderType)b slotSize:(int)n
- { return (NXCoord) info[b]->border->getSize_P(n); }
- - (NXCoord) border:(MiscBorderType)b slotMinSize:(int)n
- { return (NXCoord) info[b]->border->getMinSize_P(n); }
- - (NXCoord) border:(MiscBorderType)b slotMaxSize:(int)n
- { return (NXCoord) info[b]->border->getMaxSize_P(n); }
- - (NXCoord) border:(MiscBorderType)b slotDataSize:(int)n
- { return (NXCoord) info[b]->border->getDataSize_P(n); }
- - (BOOL) border:(MiscBorderType)b slotIsSizeable:(int)n
- { return info[b]->border->isSizeable_P(n); }
- - (BOOL) border:(MiscBorderType)b slotExpandsToData:(int)n
- { return info[b]->border->isData_P(n); }
- - (BOOL) border:(MiscBorderType)b slotIsAutosize:(int)n
- { return info[b]->border->isSpringy_P(n); }
- - (char const*) border:(MiscBorderType)b slotTitle:(int)n
- { return info[b]->border->getTitle_P(n); }
- - (int) border:(MiscBorderType)b slotTag:(int)n
- { return info[b]->border->getTag_P(n); }
- - (MiscTableCellStyle) border:(MiscBorderType)b slotCellType:(int)n
- { return info[b]->border->getStyle_P(n); }
- - border:(MiscBorderType)b slotCellPrototype:(int)n
- { return info[b]->border->getPrototype_P(n); }
-
- - (void) border:(MiscBorderType)b setSizeableSlots:(BOOL)flag
- { info[b]->border->setSizeable(flag); }
- - (void) border:(MiscBorderType)b setDraggableSlots:(BOOL)flag
- { info[b]->border->setDraggable(flag); }
- - (void) border:(MiscBorderType)b setModifierDragSlots:(BOOL)flag
- { info[b]->border->setModifierDrag(flag); }
- - (void) border:(MiscBorderType)b setUniformSizeSlots:(NXCoord)uniform_size
- {
- MiscBorderInfo* const ip = info[b];
- if (ip->border->setUniformSize((MiscPixels)floor(uniform_size)))
- {
- [self constrainSize];
- if (b == MISC_ROW_BORDER)
- {
- [self setLineScroll:uniform_size];
- [self setPageScroll:uniform_size];
- }
- [self update];
- }
- }
-
- - (void) border:(MiscBorderType)b setSlot:(int)n size:(NXCoord)size
- {
- info[b]->border->setSize_P( n, (MiscPixels)floor(size) );
- [self constrainSize];
- }
- - (void) border:(MiscBorderType)b setSlot:(int)n minSize:(NXCoord)size
- {
- info[b]->border->setMinSize_P( n, (MiscPixels)floor(size) );
- [self constrainSize];
- }
- - (void) border:(MiscBorderType)b setSlot:(int)n maxSize:(NXCoord)size
- {
- info[b]->border->setMaxSize_P( n, (MiscPixels)floor(size) );
- [self constrainSize];
- }
- - (void) border:(MiscBorderType)b setSlot:(int)n dataSize:(NXCoord)size
- { info[b]->border->setDataSize_P( n, (MiscPixels)floor(size) ); }
- - (void) border:(MiscBorderType)b setSlot:(int)n sizeable:(BOOL)flag
- { info[b]->border->setSizeable_P( n, flag ); }
- - (void) border:(MiscBorderType)b setSlot:(int)n expandsToData:(BOOL)flag
- { info[b]->border->setData_P( n, flag ); }
- - (void) border:(MiscBorderType)b setSlot:(int)n autosize:(BOOL)flag
- {
- info[b]->border->setSpringy_P( n, flag );
- [self constrainSize];
- }
-
- - (void) border:(MiscBorderType)b setSlot:(int)n title:(char const*)title
- {
- MiscBorderInfo* const ip = info[b];
- if (ip->border->setTitle_P( n, title ) && ip->isOn)
- [self border:b drawSlotTitle:n];
- }
-
- - (void) border:(MiscBorderType)b setSlot:(int)n tag:(int)x
- { info[b]->border->setTag_P( n, x ); }
- - (void) border:(MiscBorderType)b setSlot:(int)n
- cellType:(MiscTableCellStyle)type
- { info[b]->border->setStyle_P(n,type); }
- - (void) border:(MiscBorderType)b setSlot:(int)n cellPrototype:p
- { info[b]->border->setPrototype_P(n,p); }
-
-
-
- //-----------------------------------------------------------------------------
- // COL methods
- //-----------------------------------------------------------------------------
- - (MiscTableBorder*) colBorder
- { return colInfo.border; }
- - (BOOL) colTitlesOn
- { return [self borderTitlesOn:MISC_COL_BORDER]; }
- - (BOOL) setColTitlesOn:(BOOL)x
- { return [self setBorder:MISC_COL_BORDER on:x]; }
- - (MiscTableTitleMode) colTitleMode
- { return [self borderTitleMode:MISC_COL_BORDER]; }
- - (void) setColTitleMode:(MiscTableTitleMode)x
- { [self border:MISC_COL_BORDER setTitleMode:x]; }
-
- - moveColFrom:(int)fromPos to:(int)toPos
- { return [self border:MISC_COL_BORDER moveSlotFrom:fromPos to:toPos]; }
- - (int) colPosition:(int)n
- { return [self border:MISC_COL_BORDER slotPosition:n]; }
- - (int) colAtPosition:(int)n
- { return [self border:MISC_COL_BORDER slotAtPosition:n]; }
-
- - (BOOL) sizeableCols
- { return [self sizeableSlots:MISC_COL_BORDER]; }
- - (BOOL) draggableCols
- { return [self draggableSlots:MISC_COL_BORDER]; }
- - (BOOL) modifierDragCols
- { return [self modifierDragSlots:MISC_COL_BORDER]; }
- - (NXCoord) uniformSizeCols
- { return [self uniformSizeSlots:MISC_COL_BORDER]; }
-
- - (NXCoord) colAdjustedSize:(int)n
- { return [self border:MISC_COL_BORDER slotAdjustedSize:n]; }
- - (NXCoord) colSize:(int)n
- { return [self border:MISC_COL_BORDER slotSize:n]; }
- - (NXCoord) colMinSize:(int)n
- { return [self border:MISC_COL_BORDER slotMinSize:n]; }
- - (NXCoord) colMaxSize:(int)n
- { return [self border:MISC_COL_BORDER slotMaxSize:n]; }
- - (NXCoord) colDataSize:(int)n
- { return [self border:MISC_COL_BORDER slotDataSize:n]; }
- - (BOOL) colIsSizeable:(int)n
- { return [self border:MISC_COL_BORDER slotIsSizeable:n]; }
- - (BOOL) colExpandsToData:(int)n
- { return [self border:MISC_COL_BORDER slotExpandsToData:n]; }
- - (BOOL) colIsAutosize:(int)n
- { return [self border:MISC_COL_BORDER slotIsAutosize:n]; }
- - (char const*) colTitle:(int)n
- { return [self border:MISC_COL_BORDER slotTitle:n]; }
- - (int) colTag:(int)n
- { return [self border:MISC_COL_BORDER slotTag:n]; }
- - (MiscTableCellStyle) colCellType:(int)n
- { return [self border:MISC_COL_BORDER slotCellType:n]; }
- - colCellPrototype:(int)n
- { return [self border:MISC_COL_BORDER slotCellPrototype:n]; }
-
- - (void) setSizeableCols:(BOOL)flag
- { [self border:MISC_COL_BORDER setSizeableSlots:flag]; }
- - (void) setDraggableCols:(BOOL)flag
- { [self border:MISC_COL_BORDER setDraggableSlots:flag]; }
- - (void) setModifierDragCols:(BOOL)flag
- { [self border:MISC_COL_BORDER setModifierDragSlots:flag]; }
- - (void) setUniformSizeCols:(NXCoord)size
- { [self border:MISC_COL_BORDER setUniformSizeSlots:size]; }
-
- - (void) setCol:(int)n size:(NXCoord)size
- { [self border:MISC_COL_BORDER setSlot:n size:size]; }
- - (void) setCol:(int)n minSize:(NXCoord)size
- { [self border:MISC_COL_BORDER setSlot:n minSize:size]; }
- - (void) setCol:(int)n maxSize:(NXCoord)size
- { [self border:MISC_COL_BORDER setSlot:n maxSize:size]; }
- - (void) setCol:(int)n dataSize:(NXCoord)size
- { [self border:MISC_COL_BORDER setSlot:n dataSize:size]; }
- - (void) setCol:(int)n sizeable:(BOOL)flag
- { [self border:MISC_COL_BORDER setSlot:n sizeable:flag]; }
- - (void) setCol:(int)n expandsToData:(BOOL)flag
- { [self border:MISC_COL_BORDER setSlot:n expandsToData:flag]; }
- - (void) setCol:(int)n autosize:(BOOL)flag
- { [self border:MISC_COL_BORDER setSlot:n autosize:flag]; }
- - (void) setCol:(int)n title:(char const*)title
- { [self border:MISC_COL_BORDER setSlot:n title:title]; }
- - (void) setCol:(int)n tag:(int)x
- { [self border:MISC_COL_BORDER setSlot:n tag:x]; }
- - (void) setCol:(int)n cellType:(MiscTableCellStyle)x
- { [self border:MISC_COL_BORDER setSlot:n cellType:x]; }
- - (void) setCol:(int)n cellPrototype:p
- { [self border:MISC_COL_BORDER setSlot:n cellPrototype:p]; }
-
-
- //-----------------------------------------------------------------------------
- // ROW methods
- //-----------------------------------------------------------------------------
- - (MiscTableBorder*) rowBorder
- { return rowInfo.border; }
- - (BOOL) rowTitlesOn
- { return [self borderTitlesOn:MISC_ROW_BORDER]; }
- - (BOOL) setRowTitlesOn:(BOOL)x
- { return [self setBorder:MISC_ROW_BORDER on:x]; }
- - (MiscTableTitleMode) rowTitleMode
- { return [self borderTitleMode:MISC_ROW_BORDER]; }
- - (void) setRowTitleMode:(MiscTableTitleMode)x
- { [self border:MISC_ROW_BORDER setTitleMode:x]; }
-
- - moveRowFrom:(int)fromPos to:(int)toPos
- { return [self border:MISC_ROW_BORDER moveSlotFrom:fromPos to:toPos]; }
- - (int) rowPosition:(int)n
- { return [self border:MISC_ROW_BORDER slotPosition:n]; }
- - (int) rowAtPosition:(int)n
- { return [self border:MISC_ROW_BORDER slotAtPosition:n]; }
-
- - (BOOL) sizeableRows
- { return [self sizeableSlots:MISC_ROW_BORDER]; }
- - (BOOL) draggableRows
- { return [self draggableSlots:MISC_ROW_BORDER]; }
- - (BOOL) modifierDragRows
- { return [self modifierDragSlots:MISC_ROW_BORDER]; }
- - (NXCoord) uniformSizeRows
- { return [self uniformSizeSlots:MISC_ROW_BORDER]; }
-
- - (NXCoord) rowAdjustedSize:(int)n
- { return [self border:MISC_ROW_BORDER slotAdjustedSize:n]; }
- - (NXCoord) rowSize:(int)n
- { return [self border:MISC_ROW_BORDER slotSize:n]; }
- - (NXCoord) rowMinSize:(int)n
- { return [self border:MISC_ROW_BORDER slotMinSize:n]; }
- - (NXCoord) rowMaxSize:(int)n
- { return [self border:MISC_ROW_BORDER slotMaxSize:n]; }
- - (NXCoord) rowDataSize:(int)n
- { return [self border:MISC_ROW_BORDER slotDataSize:n]; }
- - (BOOL) rowIsSizeable:(int)n
- { return [self border:MISC_ROW_BORDER slotIsSizeable:n]; }
- - (BOOL) rowExpandsToData:(int)n
- { return [self border:MISC_ROW_BORDER slotExpandsToData:n]; }
- - (BOOL) rowIsAutosize:(int)n
- { return [self border:MISC_ROW_BORDER slotIsAutosize:n]; }
- - (char const*) rowTitle:(int)n
- { return [self border:MISC_ROW_BORDER slotTitle:n]; }
- - (int) rowTag:(int)n
- { return [self border:MISC_ROW_BORDER slotTag:n]; }
- - (MiscTableCellStyle) rowCellType:(int)n
- { return [self border:MISC_ROW_BORDER slotCellType:n]; }
- - rowCellPrototype:(int)n
- { return [self border:MISC_ROW_BORDER slotCellPrototype:n]; }
-
- - (void) setSizeableRows:(BOOL)flag
- { [self border:MISC_ROW_BORDER setSizeableSlots:flag]; }
- - (void) setDraggableRows:(BOOL)flag
- { [self border:MISC_ROW_BORDER setDraggableSlots:flag]; }
- - (void) setModifierDragRows:(BOOL)flag
- { [self border:MISC_ROW_BORDER setModifierDragSlots:flag]; }
- - (void) setUniformSizeRows:(NXCoord)size
- { [self border:MISC_ROW_BORDER setUniformSizeSlots:size]; }
-
- - (void) setRow:(int)n size:(NXCoord)size
- { [self border:MISC_ROW_BORDER setSlot:n size:size]; }
- - (void) setRow:(int)n minSize:(NXCoord)size
- { [self border:MISC_ROW_BORDER setSlot:n minSize:size]; }
- - (void) setRow:(int)n maxSize:(NXCoord)size
- { [self border:MISC_ROW_BORDER setSlot:n maxSize:size]; }
- - (void) setRow:(int)n dataSize:(NXCoord)size
- { [self border:MISC_ROW_BORDER setSlot:n dataSize:size]; }
- - (void) setRow:(int)n sizeable:(BOOL)flag
- { [self border:MISC_ROW_BORDER setSlot:n sizeable:flag]; }
- - (void) setRow:(int)n expandsToData:(BOOL)flag
- { [self border:MISC_ROW_BORDER setSlot:n expandsToData:flag]; }
- - (void) setRow:(int)n autosize:(BOOL)flag
- { [self border:MISC_ROW_BORDER setSlot:n autosize:flag]; }
- - (void) setRow:(int)n title:(char const*)title
- { [self border:MISC_ROW_BORDER setSlot:n title:title]; }
- - (void) setRow:(int)n tag:(int)x
- { [self border:MISC_ROW_BORDER setSlot:n tag:x]; }
- - (void) setRow:(int)n cellType:(MiscTableCellStyle)x
- { [self border:MISC_ROW_BORDER setSlot:n cellType:x]; }
- - (void) setRow:(int)n cellPrototype:p
- { [self border:MISC_ROW_BORDER setSlot:n cellPrototype:p]; }
-
- //-----------------------------------------------------------------------------
- // - read:selector:
- //-----------------------------------------------------------------------------
- - (SEL) read:(int)ver selector:(NXTypedStream*)stream
- {
- SEL cmd = 0;
- char* str;
- NXReadType( stream, @encode(char*), &str );
- if (str != 0)
- {
- if (*str != '\0')
- cmd = sel_getUid( str );
- free( str );
- }
- return cmd;
- }
-
-
- //-----------------------------------------------------------------------------
- // - read:globalInfo:
- //
- // NOTE: Cannot archive sort_entry_func and sort_slot_func because they
- // are function addresses.
- //-----------------------------------------------------------------------------
- - (void) read:(int)ver globalInfo:(NXTypedStream*)stream
- {
- NXReadType( stream, @encode(int), &tag );
- NXReadType( stream, @encode(BOOL), &enabled );
- NXReadType( stream, @encode(BOOL), &lazy );
- NXReadType( stream, @encode(MiscSelectionMode), &mode );
- font = NXReadObject( stream );
- textColor = NXReadColor( stream );
- backgroundColor = NXReadColor( stream );
- highlightTextColor = NXReadColor( stream );
- highlightBackgroundColor = NXReadColor( stream );
- nextText = NXReadObject( stream );
- previousText= NXReadObject( stream );
- delegate = NXReadObject( stream );
- dataDelegate= NXReadObject( stream );
- target = NXReadObject( stream );
- doubleTarget= NXReadObject( stream );
- action = [self read:ver selector:stream];
- doubleAction = [self read:ver selector:stream];
- }
-
-
- //-----------------------------------------------------------------------------
- // - read:border:stream:
- //-----------------------------------------------------------------------------
- - (void) read:(int)ver border:(MiscBorderInfo*)p stream:(NXTypedStream*)stream
- {
- NXZone* const z = [self zone];
- int n;
- if (p->sort_vector != 0)
- NXZoneFree( z, p->sort_vector );
- NXReadType( stream, @encode(int), &(n) );
- if (n > 0)
- {
- p->sort_vector_len = n;
- p->sort_vector = (int*) NXZoneMalloc( z, n * sizeof(int) );
- for (int i = 0; i < n; i++)
- NXReadType( stream, @encode(int), &(p->sort_vector[i]) );
- }
- else
- {
- p->sort_vector_len = 0;
- p->sort_vector = 0;
- }
- NXReadType( stream, @encode(BOOL), &(p->isOn) );
- NXReadType( stream, @encode(BOOL), &(p->autoSort) );
- NXReadType( stream, @encode(BOOL), &(p->constrain_min) );
- NXReadType( stream, @encode(BOOL), &(p->constrain_max) );
- if (p->border == 0)
- p->border = new( NXZoneMalloc( z, sizeof(*(p->border)) ) )
- MiscTableBorder( MISC_ROW_BORDER );
- p->border->read( stream ); // FIXME: Should send ver.
- }
-
-
- //-----------------------------------------------------------------------------
- // - read:cells:
- //
- // FIXME: What happens when a non-empty non-lazy TableScroll reads the data
- // from a lazy, empty one. Does the memory get freed?
- //-----------------------------------------------------------------------------
- - (void) read:(int)ver cells: (NXTypedStream*) stream
- {
- NXReadType( stream, @encode(int), &num_cols );
- NXReadType( stream, @encode(int), &num_rows );
- max_rows = num_rows;
- if (lazy)
- {
- max_cells = 0;
- cells = 0;
- }
- else // (!lazy)
- {
- max_cells = max_rows * num_cols;
- if (max_cells == 0)
- cells = 0;
- else
- {
- int const nbytes = max_cells * sizeof(*cells);
- cells = (id*) NXZoneMalloc( [self zone], nbytes );
- id* p = cells;
- for (int r = 0; r < num_rows; r++)
- for (int c = 0; c < num_cols; c++)
- *p++ = NXReadObject( stream );
- }
- }
- }
-
-
- //-----------------------------------------------------------------------------
- // - read:
- //-----------------------------------------------------------------------------
- - read: (NXTypedStream*) stream
- {
- [super read:stream];
- char const* class_name = [[MiscTableScroll class] name];
- int ver = NXTypedStreamClassVersion( stream, class_name );
- if (((unsigned int)ver) > ((unsigned int)MISC_TS_VERSION))
- [self error:"%s: old library (version %d), can't -read: "
- "new object (version %d).\n",
- class_name,
- MISC_TS_VERSION, ver ];
- [self read:ver globalInfo:stream];
- [self read:ver border:&colInfo stream:stream];
- [self read:ver border:&rowInfo stream:stream];
- [self read:ver cells:stream];
- [self doInit:ver];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // - writeSelector:stream:
- //-----------------------------------------------------------------------------
- - (void) writeSelector: (SEL) cmd stream: (NXTypedStream*) stream
- {
- char const* str = 0;
- if (cmd != 0)
- str = sel_getName( cmd );
- if (str == 0) // not an 'else if'
- str = "";
- NXWriteType( stream, @encode(char*), &str );
- }
-
-
- //-----------------------------------------------------------------------------
- // - writeGlobalInfo:
- //
- // NOTE: Cannot archive sort_entry_func and sort_slot_func because they
- // are function addresses.
- //-----------------------------------------------------------------------------
- - (void) writeGlobalInfo: (NXTypedStream*) stream
- {
- NXWriteType( stream, @encode(int), &tag );
- NXWriteType( stream, @encode(BOOL), &enabled );
- NXWriteType( stream, @encode(BOOL), &lazy );
- NXWriteType( stream, @encode(MiscSelectionMode), &mode );
- NXWriteObject( stream, font );
- NXWriteColor( stream, textColor );
- NXWriteColor( stream, backgroundColor );
- NXWriteColor( stream, highlightTextColor );
- NXWriteColor( stream, highlightBackgroundColor );
- NXWriteObjectReference( stream, nextText );
- NXWriteObjectReference( stream, previousText );
- NXWriteObjectReference( stream, delegate );
- NXWriteObjectReference( stream, dataDelegate );
- NXWriteObjectReference( stream, target );
- NXWriteObjectReference( stream, doubleTarget );
- [self writeSelector: action stream: stream];
- [self writeSelector: doubleAction stream: stream];
- }
-
-
- //-----------------------------------------------------------------------------
- // - writeBorder:stream:
- //-----------------------------------------------------------------------------
- - (void) writeBorder:(MiscBorderInfo*)p stream:(NXTypedStream*)stream
- {
- int const n = p->sort_vector_len;
- NXWriteType( stream, @encode(int), &(n) );
- if (n > 0)
- for (int i = 0; i < n; i++)
- NXWriteType( stream, @encode(int), &(p->sort_vector[i]) );
- NXWriteType( stream, @encode(BOOL), &(p->isOn) );
- NXWriteType( stream, @encode(BOOL), &(p->autoSort) );
- NXWriteType( stream, @encode(BOOL), &(p->constrain_min) );
- NXWriteType( stream, @encode(BOOL), &(p->constrain_max) );
- p->border->write( stream );
- }
-
-
- //-----------------------------------------------------------------------------
- // - writeCells:
- //-----------------------------------------------------------------------------
- - (void) writeCells: (NXTypedStream*) stream
- {
- NXWriteType( stream, @encode(int), &num_cols );
- NXWriteType( stream, @encode(int), &num_rows );
- if (!lazy)
- for (int r = 0; r < num_rows; r++)
- for (int c = 0; c < num_cols; c++)
- NXWriteObject( stream, [self cellAt:r:c] );
- }
-
-
- //-----------------------------------------------------------------------------
- // - write:
- //-----------------------------------------------------------------------------
- - write: (NXTypedStream*) stream
- {
- // Ensure that subviews are NOT archived.
- if (colInfo.isOn) [colInfo.clip removeFromSuperview];
- if (rowInfo.isOn) [rowInfo.clip removeFromSuperview];
- if (rowInfo.isOn && colInfo.isOn) [nullView removeFromSuperview];
- [tableView removeFromSuperview];
-
- [super write:stream];
- [self writeGlobalInfo:stream];
- [self writeBorder:&colInfo stream:stream];
- [self writeBorder:&rowInfo stream:stream];
- [self writeCells:stream];
-
- // Restore state.
- [self setDocView: tableView];
- if (colInfo.isOn) [self addSubview:colInfo.clip];
- if (rowInfo.isOn) [self addSubview:rowInfo.clip];
- if (rowInfo.isOn && colInfo.isOn) [self addSubview:nullView];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // DRAWING
- //-----------------------------------------------------------------------------
-
- - drawCellAt:(int)row :(int)col
- {
- [tableView drawCellAt:row:col];
- [window flushWindow];
- return self;
- }
- - drawRow:(int)row
- {
- [tableView drawRow:row];
- [window flushWindow];
- return self;
- }
- - drawCol:(int)col
- {
- [tableView drawCol:col];
- [window flushWindow];
- return self;
- }
- - border:(MiscBorderType)b drawSlot:(int)n
- { return (b == MISC_COL_BORDER) ? [self drawCol:n] : [self drawRow:n]; }
-
- - border:(MiscBorderType)b drawSlotTitle:(int)n // physical position.
- {
- MiscBorderInfo* const ip = info[b];
- if (ip->isOn) // visual position.
- {
- [ip->view drawSlot: [self border:b slotPosition:n]];
- [window flushWindow];
- }
- return self;
- }
- - drawRowTitle:(int)n { return [self border:MISC_ROW_BORDER drawSlotTitle:n]; }
- - drawColTitle:(int)n { return [self border:MISC_COL_BORDER drawSlotTitle:n]; }
-
- - (void) reflectSelection
- {
- if ([self canDraw])
- {
- [window disableFlushWindow];
- [rowInfo.view reflectSelection];
- [colInfo.view reflectSelection];
- [tableView reflectSelection];
- [[window reenableFlushWindow] flushWindow];
- }
- else
- [self setNeedsDisplay:YES];
- }
-
- - setAutodisplay:(BOOL) x
- {
- [rowInfo.view setAutodisplay:x];
- [colInfo.view setAutodisplay:x];
- [tableView setAutodisplay:x];
- return [super setAutodisplay:x];
- }
-
- - (void) scrollCellToVisible: (int)row : (int) col
- { [tableView scrollCellToVisible: row:col]; }
- - (void) scrollRowToVisible: (int)row { [tableView scrollRowToVisible:row]; }
- - (void) scrollColToVisible: (int)col { [tableView scrollColToVisible:col]; }
- - scrollSelToVisible
- {
- if ([self hasRowSelection])
- [self scrollRowToVisible: [self selectedRow]];
- else if ([self hasColSelection])
- [self scrollColToVisible: [self selectedCol]];
- return self;
- }
-
-
- //-----------------------------------------------------------------------------
- // MOUSE & KEYBOARD TRACKING
- //-----------------------------------------------------------------------------
- - (void) trackBy: (MiscBorderType)b { [tableView trackBy:b]; }
- - (MiscBorderType) trackingBy { return [tableView trackingBy]; }
-
- @end
-